#include "mainwindow.h"
#include "ui_mainwindow.h"

#define NETTESTTIME 500   //网络监测器间隔时间
#define NETTESTAROUND 3000 //网络监测器检测周期
#define VERSION 130924

QString QWebPageIE::userAgentForUrl ( const QUrl & url ) const //全局函数返回一个IE浏览器的UA
{
    return "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7)";
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ctwlan = new QNetworkAccessManager(this);
    QObject::connect(ctwlan, SIGNAL(finished(QNetworkReply*)),
                 this, SLOT(finishedSlot(QNetworkReply*)));

    QWebPageIE *pageIE = new QWebPageIE();      //IE浏览器UA变量

    QUrl cturllogin("http://wlan.ct10000.com/portal4HN"); //程序初期化的时候访问CT10000防止404错误
    ui->webCT10000->setPage(pageIE);                //设置UA为IE的，防止弹出信息
    ui->webCT10000->load(cturllogin);             //加载CT10000页面

    ui->pbDisconnect->setEnabled(false); //默认设置断开连接不可用
    ui->pbLogin->setDefault(true);      //设置登陆按钮为默认按钮

    timer = new QTimer(this);   //网络监测定时器
    connect(timer,SIGNAL(timeout()),SLOT(onTime())); //连接定时器与成员函数onTime
    nWANConnect=nCTLanConnect=0; //网络监测计数器初始化
    isRedial=0;    //默认表示不是自动重拨的
    haveError=0;        //默认表示没有错误
    //timer->start(NETTESTAROUND);  //测试用

    systray(); //系统托盘

    QString conf="config.sys"; //设定配置文件
    QSettings settings(conf,QSettings::IniFormat);

    if(settings.value("first").toInt())
        QMessageBox::information(this,QString::fromUtf8("初使用 - 帮助信息"),QString::fromUtf8("<h1>你好！欢迎来到天翼世界！</h1><hr/>这里是中国电信天翼拨号客户端，我可以带领你轻松连接到中国电信天翼互联网！对于初使用的你，为了让你更了解我，那么请花几分钟读完这里吧！<br/><br/>我的主界面上面有两个输入框，它们分别是<b>手机号码</b>和<b>用户密码</b>，那么我就来讲解下它们的详细作用吧！<br/><b>手机号码</b> 这里填写你的天翼无线宽带账号<br/><b>用户密码</b> 这里填写你的天翼无线宽带账号的密码<br/><br/>好啦，当我们填写完这些信息之后呢，你只需要点击界面右下角的<b>登陆</b>按钮，稍等大约10秒钟左右就能连接到互联网，再稍等10秒钟左右就能在主界面的左下角显示您当前网络的状况，具体可能会有下面几种状况：<br/><b>互联网</b> 表示你现在可以直接打开网络浏览器进行上网冲浪<br/><b>未登录</b> 表示你的账号可能登陆失败或者账号中断了，在这种情况下软件会自动重新拨号，若多次重新拨号依旧无法登陆，那么可能你的账号出现了问题<br/><b>已掉线</b> 如果出现这种提示的话，首先检查你的网线是否连接好，然后查看设备是否运行正常，若都正常可能是中国电信网关出现问题<br/><br/>那么如果你不想上网了怎么办呢？我们只需要点击界面上的<b>断开连接</b>即可断开与互联网的连接，此时也不会自动拨号了，那么现在就开始我们的互联网之旅吧。<br/><b>注意！</b> 对于W开头的账号是不能使用本软件进行拨号的！"));

    settings.setValue("first","0");  //表示程序不是第一次启动了

    ui->lePhonenumber->setText(settings.value("phonenum").toString()); //读取上次输入的手机号码
    ui->leUserpassword->setText(settings.value("password").toString()); //读取上次输入的手机密码
    if(settings.value("debug").toInt())    //诊断信息
    {
        ui->actionDebug->setChecked(true);
    }
    else
    {
        ui->actionDebug->setChecked(false);
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onTime()
{
    if(isRedial)
        nWANConnect=nCTLanConnect=5; //计数器清5
    else
        nWANConnect=nCTLanConnect=0; //计数器清0

    for(int i=0;i<3;i++)
    {
        ncsi.connectToHost("61.186.95.108", 80);    //连接到电信验证服务器
        if(ncsi.waitForConnected(500))
        {
            onCTLanconnected();
        }

        sleep(NETTESTTIME);

        ncsi.connectToHost("65.55.96.11", 25);  //连接到外网服务器
        //ncsi.connectToHost("1.2.3.4", 80);  //测试用
        if(ncsi.waitForConnected(500))
        {
            onWANconnected();
        }

        sleep(NETTESTTIME);
    }

    qDebug("nWAN:%d\tnCTLan:%d",nWANConnect,nCTLanConnect);//调试时显示信息

    if(nWANConnect==0&&nCTLanConnect>=2)  //外网无法连接，验证服务器可以连接表示未登录
    {
        ui->lblOnline->setText("未登录");
        onUserLogin(0); //登陆函数不提示消息
    }
    else if(nWANConnect==0&&nCTLanConnect==0)  //登陆服务器与外网同时无法连接表示网络中断
    {
        ui->lblOnline->setText("已掉线");
        isRedial=0;
        systemTray->showMessage("网络故障", "您的网络已经掉线！");
    }
    else if(nWANConnect>=1)   //外网能连接表示连接正常并连接到互联网
    {
        ui->lblOnline->setText("互联网");
        isRedial=0;
    }

    qDebug("Tested!");//调试时显示信息
}

void MainWindow::onWANconnected()
{
    nWANConnect++;
    qDebug("WAN Connected!");//调试时显示信息

    sleep(1000);
    ncsi.abort();
    ncsi.close();
}

void MainWindow::onCTLanconnected()
{
    nCTLanConnect++;
    qDebug("CTLAN Connected!");//调试时显示信息

    sleep(1000);
    ncsi.abort();
    ncsi.close();
}

void MainWindow::sleep(unsigned int msec) //延时器来自blog.fcsys.us
{
    QEventLoop eventloop;
        QTimer::singleShot(msec, &eventloop, SLOT(quit()));
        eventloop.exec();
}

void MainWindow::webrsa_reload() //刷新PHP服务器生成密钥文件
{
    ui->webCtrsa->reload();     //页面刷新让服务器读取cookies
    ui->webCtrsa->disconnect(); //断开连接器，防止无限刷新
}

void MainWindow::onUserLogin(int isPushed)
{
    if(isPushed)
        isRedial=1;
    else
        isRedial=0;

    if((ui->lePhonenumber->text()==""||ui->lePhonenumber->text().length()!=11)||ui->leUserpassword->text()=="")
    {  //【2013年9月25日：来自客户的反应空账号可以登陆加入判断修复此问题】
        QMessageBox::critical(this,"错误信息","您的手机号码或者密码输入错误请重新输入！");
        return ;
    }
    timer->stop();   //若用户选择自动重拨先临时禁用

    ui->pbLogin->setEnabled(false); //登陆开始后禁止用户点击登陆
    ui->pbDisconnect->setEnabled(false); //登陆开始后禁止用户点击断开连接

    ui->lblOnline->setText("内核启动中");
    QProcess *mphpproc = new QProcess;  //新建进程用于启动迷你PHP服务器
    mphpproc->start("mphp.bat");
    sleep(1500);  //等待1.5秒等待服务器启动完毕

    ui->lblOnline->setText("密码生成中");
    QUrl url("http://127.0.0.1:32872/ctpassword.php?cta="+ui->leUserpassword->text());
    ui->webCtrsa->load(url);                //执行RSA密钥生成程序
    connect(ui->webCtrsa,SIGNAL(loadFinished(bool)),this,SLOT(webrsa_reload()));//刷新服务器获取Cookies

    ui->lblOnline->setText("密码获取中");
    sleep(500);                            //休息0.5秒钟，让服务器建立ctrsa.pem文件
    url="http://127.0.0.1:32872/ctrsa.pem";    //服务器端ctrsa.pem文件路径
    QNetworkReply* reply = ctwlan->get(QNetworkRequest(url));
    // NOTE: Store QNetworkReply pointer (maybe into caller).
    // When this HTTP requdest is finished you will receive this same
    // QNetworkReply as response parameter.
    // By the QNetworkReply pointer you can identify request and response.

    ui->lblOnline->setText("登录中");
    sleep(500);                            //休息0.5秒钟，让服务器建立ctrsa.pem文件
    kortimeunix=QDateTime::currentDateTime();//取得Unix时间戳
    QString ctloginurl="http://wlan.ct10000.com/portal4HN/PhoneUserLogin?phoneNumber="+ui->lePhonenumber->text()+"&phonePassword="+ctrsakey+"&checkCode=&basIp=&checkCode=&intranetIp=&time="+QString::number(kortimeunix.toTime_t());
    ui->teDebug->setText(ctloginurl);       //仅供调试使用

    ui->lblOnline->setText("关闭内核中");
    QProcess *mphpstop = new QProcess;  //新建进程用于停止迷你PHP服务器
    mphpstop->start("stopphp.bat");

    QUrl cturllogin("http://wlan.ct10000.com/");
    ui->webCT10000->load(cturllogin);   //先加载出电讯登陆界面
    sleep(4000);                         //休息4.0秒就行了，不然就会弹出界面
    ui->webCT10000->load(ctloginurl);   //因为登陆页面坑爹只好用WebView登陆
    sleep(2000);                        //休息2.0秒钟，等待登陆结果返回

    if(ui->webCT10000->findText("0#-1#0#"))
    {
        ui->lblOnline->setText("登陆成功");
        ui->pbDisconnect->setEnabled(true); //设置断开连接为可用
        haveError=0;
    }
    else if(ui->webCT10000->findText("1#-1#0#"))
    {
        ui->lblOnline->setText("账号不正确");
        if(isPushed) QMessageBox::critical(this,"账号问题","您的账号可能不正确或者已经过期请核实您的登陆账号或者密码后重新登陆。");
        timer->stop();
        haveError=1;
    }
    else if(ui->webCT10000->findText("2#-1#0#"))
    {
        ui->lblOnline->setText("登陆成功");
        if(isPushed) QMessageBox::information(this,"提示","您目前已经连接到互联网，请勿重复登陆！");
        ui->pbDisconnect->setEnabled(true); //设置断开连接为可用
        haveError=0;
    }
    else if(ui->webCT10000->findText("-10"))
    {
        ui->lblOnline->setText("账号出现未知问题");
        if(isPushed) QMessageBox::critical(this,"账号问题","您的账号出现了未知问题，请确认您的账号与密码填写正确！");
        timer->stop();
        haveError=1;
    }
    else
    {
        ui->lblOnline->setText("登录失败");
        if(isPushed) QMessageBox::critical(this,"未知故障","请确认您的网络是否正常，请仔细检查您的网络设备连接，然后检测账号是否正常并且重新启动拨号程序重新登陆。");
        timer->stop();
        haveError=1;
    }

    ui->pbLogin->setEnabled(true); //登陆结束后允许用户点击登陆
    ui->webCT10000->load(cturllogin);   //载出电讯登陆界面，以后备用
    timer->start(NETTESTAROUND);   //自动重拨开始启用  来自mi的建议
}

void MainWindow::on_pbLogin_clicked()
{
    onUserLogin(1); //调用用户登陆

    QString conf="config.sys"; //设定配置文件
    QSettings settings(conf,QSettings::IniFormat);
    settings.setValue("phonenum",ui->lePhonenumber->text());  //保存手机号码
    settings.setValue("password",ui->leUserpassword->text());  //保存手机密码

    if(!haveError)
    {
        systemTray->show();
        if(systemTray->isVisible())
        {
            hide();
            systemTray->showMessage("天翼宽带", "天翼宽带正在后台运行，右击此处可以显示！");
        }
    }
}

void MainWindow::finishedSlot(QNetworkReply *reply)
{
#if 1
     // Reading attributes of the reply
     // e.g. the HTTP status code
     QVariant statusCodeV =
     reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
     // Or the target URL if it was a redirect:
     QVariant redirectionTargetUrl =
     reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
     // see CS001432 on how to handle this

     // no error received?
     if (reply->error() == QNetworkReply::NoError)
     {
         // read data from QNetworkReply here
         // Example 2: Reading bytes form the reply
         QByteArray bytes = reply->readAll();  // bytes
         //QString string(bytes); // string
         QString ctpwdstr = QString::fromUtf8(bytes);
         ctrsakey=ctpwdstr; //将RSA加密的密码赋值给全局变量

         ui->teDebug->setText(ctpwdstr);               //仅供测试用
        // QMessageBox::information(this,"",ctpwdstr); //仅供测试用
     }
     // Some http error received
     else
     {
         // handle errors here
     }

     // We receive ownership of the reply object
     // and therefore need to handle deletion.
     reply->deleteLater();
#endif
}

void MainWindow::on_pbDisconnect_clicked()
{
    QUrl url("http://www.coridc.com/ip/");  //获取公网IP地址API
    QNetworkReply* reply = ctwlan->get(QNetworkRequest(url));

    url="http://wlan.ct10000.com/portal4HN/CloseNet?userIp="+ctrsakey+"&basIp=&intranetIp=";  //断开网络
    reply = ctwlan->get(QNetworkRequest(url));
    ui->teDebug->setText(url.toString());       //仅供调试使用

    ui->pbDisconnect->setEnabled(false);  //断开连接后设置为不可用
    ui->lblOnline->setText("已断开");

    timer->stop();
}

void MainWindow::on_actionDebug_toggled(bool arg1)
{
    QString conf="config.sys"; //设定配置文件
    QSettings settings(conf,QSettings::IniFormat);
    if(arg1) //当点击显示诊断信息时改变窗口大小
    {
        this->setMinimumWidth(this->width()+540);
        this->setMaximumWidth(this->width()+540);
        settings.setValue("debug","1");  //保存诊断
    }
    else
    {
        this->setMinimumWidth(this->width()-540);
        this->setMaximumWidth(this->width()-540);
        settings.setValue("debug","0");  //保存诊断
    }
}

void MainWindow::on_actionAbout_triggered()
{
    QMessageBox::about(this,"关于 中国电信天翼宽带上网助手","<h1>中国电信天翼上网助手</h1><hr/>基于中国电信原生登陆网页调用编写，附带Apache迷你版服务器用于解析用户密码RSAKey，支持掉线自动重新拨号与延迟检测功能。<br/><br/>程序编写: dfc643 (北极光)<br/>程序版本：v0.3 build130925<br/>官方博客: blog.fcsys.us<br/><br/>Powered by FC-System Computer Inc.");
}

void MainWindow::on_actionExit_triggered()
{
    //qApp->quit();
    systemTray->hide();
    exit(0);
}

void MainWindow::systray()   //系统托盘代码 来自互联网
{
    QIcon icon(":/new/prefix1/icon.png");
    systemTray = new QSystemTrayIcon(this);
    systemTray->setIcon(icon);
    systemTray->setToolTip(QString::fromUtf8("天翼宽带"));
    //minimumAct = new QAction(QString::fromUtf8("隐藏窗口"), this);
    //Note the differences between hide() and showMinimized().
    //connect(minimumAct, SIGNAL(triggered()), this, SLOT(hide()));
    //maximumAct = new QAction("Maximum Window", this);
    //connect(maximumAct, SIGNAL(triggered()), this, SLOT(showMaximized()));
    restoreAct = new QAction(QString::fromUtf8("显示窗口"), this);
    connect(restoreAct, SIGNAL(triggered()), this, SLOT(showNormal()));
    quitAct = new QAction(QString::fromUtf8("退出"), this);
    connect(quitAct, SIGNAL(triggered()), this, SLOT(on_actionExit_triggered()));
    pContextMenu = new QMenu(this);
    //pContextMenu->addAction(minimumAct);
    //pContextMenu->addAction(maximumAct);
    pContextMenu->addAction(restoreAct);
    pContextMenu->addSeparator();
    pContextMenu->addAction(quitAct);
    systemTray->setContextMenu(pContextMenu);
    systemTray->hide();
}

void MainWindow::closeEvent(QCloseEvent *event)   //关闭事件重载
{
    systemTray->show();
    if(systemTray->isVisible())
    {
        hide();
        systemTray->showMessage("天翼宽带", "天翼宽带正在后台运行！");
        event->ignore();
    }
}
